using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.WindowsAzure;

namespace AzureContrib.WindowsAzure.StorageClient
{
	/// <summary>
	/// A manager that abstracts away CloudDrive from your code. All you want is to get it, use it and close it.
	/// </summary>
	/// <remarks>This manager supports enumerating any mounted drives that it manages. If a mounted drive was not created through this instance of the CloudDriveManager the StorageCredentials will not be available and will be null.</remarks>
	/// <remarks>The intent of this contract is to use it for a singleton implementation. One CloudDrive manager for the duration of the application.</remarks>
	public interface ICloudDriveManager : IEnumerable<Tuple<DirectoryInfo, Uri, StorageCredentials>>
	{
		/// <summary>
		/// Initialize the CloudDrive local disk cache.
		/// </summary>
		/// <param name="cacheRootPath">The path to the local disk cache.</param>
		/// <param name="totalCacheInMegabytes">The size of the local disk cache.</param>
		/// <remarks>This method is idempotent in the sense that it can only be called once. Once local CloudDrive cache is initialized it is what it is for the lifetime of the application.</remarks>
		void InitializeCache(DirectoryInfo cacheRootPath, int totalCacheInMegabytes);

		/// <summary>
		/// The total size of the local disk cache.
		/// </summary>
		int TotalCacheInMegabytes { get; }

		/// <summary>
		/// The remaining disk cache which has not yet been allocated to a mounted drive.
		/// </summary>
		int RemainingCache { get; }

		/// <summary>
		/// Create a cloud drive in blob storage that does not exist.
		/// </summary>
		/// <param name="storageCredentials">The Windows Azure Storage Credentials to access Cloud Storage.</param>
		/// <param name="driveAddress">The blob VHD dive.</param>
		/// <returns>True if the specific Cloud Drive (Page Blob) exists.</returns>
		/// <Exception cref="CloudDriveManagerException">If the blob exists at the location but is not a Page Blob.</Exception>
		bool Exists(StorageCredentials storageCredentials, Uri driveAddress);

		/// <summary>
		/// Create a cloud drive in blob storage that does not exist.
		/// </summary>
		/// <param name="storageCredentials">The Windows Azure Storage Credentials to access Cloud Storage.</param>
		/// <param name="driveAddress">The blob VHD dive.</param>
		/// <param name="sizeInMegabytes">If the drive to mount does not exist then create it with the given size.</param>
		void Create(StorageCredentials storageCredentials, Uri driveAddress, int sizeInMegabytes);

		/// <summary>
		/// Mount a Windows Azure Drive and return the DirectoryInfo for it.
		/// </summary>
		/// <param name="storageCredentials">The Windows Azure Storage Credentials to access Cloud Storage.</param>
		/// <param name="driveAddress">The blob VHD dive.</param>
		/// <param name="cacheSize">The local cache size to use for this drive.</param>
		/// <param name="driveMountOptions">Drive mounting options.</param>
		/// <returns></returns>
		DirectoryInfo Mount(StorageCredentials storageCredentials, Uri driveAddress, int cacheSize = 0, DriveMountOptions driveMountOptions = DriveMountOptions.Force);

		/// <summary>
		/// Unmount the drive mounted to the rootDirectory.
		/// </summary>
		/// <param name="driveRootDirectory">The root directory for the mount.</param>
		void Unmount(DirectoryInfo driveRootDirectory);

		/// <summary>
		/// Unmount and delete from blob storage the drive mounted to the rootDirectory.
		/// </summary>
		/// <param name="driveRootDirectory">The root directory for the mount.</param>
		void Delete(DirectoryInfo driveRootDirectory);
	}
}